
/* GCSx
** LAYERPROP.CPP
**
** Layer properties dialog
*/

/*****************************************************************************
** Copyright (C) 2003-2006 Janson
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
** 
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
*****************************************************************************/

#include "all.h"

LayerPropertiesRadioButton::LayerPropertiesRadioButton(int rId, const string& rLabel, int* rSetting, int rValue) : WRadioButton(rId, rLabel, rSetting, rValue) { start_func
}

int LayerPropertiesRadioButton::state(int checked, int fromLoad) { start_func
    if ((checked > 0) && (parent)) {
        Dialog* myParent = dynamic_cast<Dialog*>(parent);
    
        if (value == Layer::LAYER_EMPTY) {
            myParent->findWidget(LayerPropertiesDialog::ID_WIDTH)->disable();
            myParent->findWidget(LayerPropertiesDialog::ID_HEIGHT)->disable();
            myParent->findWidget(LayerPropertiesDialog::ID_SIZELABEL, 0)->disable();
            myParent->findWidget(LayerPropertiesDialog::ID_SIZELABEL, 1)->disable();
        }
        else {
            myParent->findWidget(LayerPropertiesDialog::ID_WIDTH)->enable();
            myParent->findWidget(LayerPropertiesDialog::ID_HEIGHT)->enable();
            myParent->findWidget(LayerPropertiesDialog::ID_SIZELABEL, 0)->enable();
            myParent->findWidget(LayerPropertiesDialog::ID_SIZELABEL, 1)->enable();
        }
        
        if (value == Layer::LAYER_TILE) {
            myParent->findWidget(LayerPropertiesDialog::ID_TILESET)->enable();
            myParent->findWidget(LayerPropertiesDialog::ID_EXTENDED)->enable();
            myParent->findWidget(LayerPropertiesDialog::ID_EFFECTS)->enable();
            dynamic_cast<WStatic*>(myParent->findWidget(LayerPropertiesDialog::ID_SIZELABEL, 0))->changeText("tiles");
            dynamic_cast<WStatic*>(myParent->findWidget(LayerPropertiesDialog::ID_SIZELABEL, 1))->changeText("tiles");
        }
        else {
            myParent->findWidget(LayerPropertiesDialog::ID_TILESET)->disable();
            myParent->findWidget(LayerPropertiesDialog::ID_EXTENDED)->disable();
            myParent->findWidget(LayerPropertiesDialog::ID_EFFECTS)->disable();
            dynamic_cast<WStatic*>(myParent->findWidget(LayerPropertiesDialog::ID_SIZELABEL, 0))->changeText("pixels");
            dynamic_cast<WStatic*>(myParent->findWidget(LayerPropertiesDialog::ID_SIZELABEL, 1))->changeText("pixels");
        }
    }
    
    return WRadioButton::state(checked, fromLoad);
}

LayerPropertiesDialog* LayerPropertiesDialog::dialog = NULL;

LayerPropertiesDialog* LayerPropertiesDialog::create() { start_func
    if (!dialog) {
        dialog = new LayerPropertiesDialog();
    }
    return dialog;
}

void LayerPropertiesDialog::destroy() { start_func
    if (dialog) {
        delete dialog;
        dialog = NULL;
    }
}

LayerPropertiesDialog::LayerPropertiesDialog() : Dialog("Layer Properties") { start_func
    initialized = 0;
}

Dialog::ButtonAction LayerPropertiesDialog::verifyEntry(int buttonId, Dialog::ButtonAction buttonType) { start_func
    if ((buttonType != BUTTON_APPLY) && (buttonType != BUTTON_OK)) return BUTTON_DEFAULT;

    // Another layer with same name?
    string lName = dynamic_cast<WTextBox*>(findWidget(ID_NAME))->state();
    toLower(lName);
    int found = layer->getScene()->findLayer(lName);
    if ((found >= 0) && (layer->getScene()->getLayer(found) != layer)) {
        guiErrorBox("A layer by that name already exists in this scene- please choose another.", errorTitleDuplicateName);
        return BUTTON_NOTHING;
    }
    
    if (lName.empty()) {
        guiErrorBox("Please enter a name for this layer.", errorTitleMissingName);
        return BUTTON_NOTHING;
    }
    
    // @TODO: image/font layers may have different sizing requirements
    // @TODO: Reduction in size causes warning if not new

    return Dialog::verifyEntry(buttonId, buttonType);
}

int LayerPropertiesDialog::run(int allowTypeChange, Layer::LayerType* type, string* title, int* xSize, int* ySize, int* tilesetId, int* usesExtended, int* usesEffects, const LayerEdit* whichLayer) { start_func
    int typeInt = *type;
    layer = whichLayer;
    *usesExtended = *usesExtended ? 1 : 0;
    *usesEffects = *usesEffects ? 1 : 0;

    if (!initialized) {
        Widget* w = NULL;
    
        w = new WStatic(ID_LABEL, "\tName:");
        w->addTo(this);

        w = new WTextBox(ID_NAME, title, 0);
        w->addTo(this);

        w = new LayerPropertiesRadioButton(ID_TYPE, "\tEmpty layer", &typeInt, Layer::LAYER_EMPTY);
        w->addTo(this);

        w = new LayerPropertiesRadioButton(ID_TYPE, "\tTile layer", &typeInt, Layer::LAYER_TILE);
        w->addTo(this);

        w = new LayerPropertiesRadioButton(ID_TYPE, "\tImage layer", &typeInt, Layer::LAYER_IMAGE);
        w->addTo(this);

        w = new LayerPropertiesRadioButton(ID_TYPE, "\tFont layer", &typeInt, Layer::LAYER_FONT);
        w->addTo(this);

        w = new WCheckBox(ID_EXTENDED, "E\txtended data", usesExtended, 1);
        w->setToolTip("Extended data allows customizing collision maps, alpha (translucency), and animation");
        w->addTo(this);

        w = new WCheckBox(ID_EFFECTS, "E\tffects data", usesEffects, 1);
        w->setToolTip("Effects data is currently unused");
        w->addTo(this);

        w = new WStatic(ID_LABEL, "\tLibrary:");
        w->addTo(this);

        w = new WListBox(ID_TILESET, tilesetId);
        w->addTo(this);

        makePretty();

        w = new WStatic(ID_LABEL, "\tWidth:");
        w->addTo(this);

        w = new WNumberBox(ID_WIDTH, xSize, 1, MAX_LAYERTILESIZE);
        w->addTo(this);

        w = new WStatic(ID_SIZELABEL, "tiles");
        w->addTo(this);

        w = new WStatic(ID_LABEL, "\tHeight:");
        w->addTo(this);
        
        w = new WNumberBox(ID_HEIGHT, ySize, 1, MAX_LAYERTILESIZE);
        w->addTo(this);

        w = new WStatic(ID_SIZELABEL, "tiles");
        w->addTo(this);
        
        w = new WButton(ID_OK, messageBoxOK, BUTTON_OK);
        w->addTo(this);
        
        w = new WButton(ID_CANCEL, messageBoxCancel, BUTTON_CANCEL);
        w->addTo(this);
        
        makePretty(3, 1, 1);
        
        initialized = 1;
    }
    else {
        findWidget(ID_NAME)->changeStorage(title);
        for (int pos = 0; pos < 4; ++pos) {
            findWidget(ID_TYPE, pos)->changeStorage(&typeInt);
        }
        findWidget(ID_WIDTH)->changeStorage(xSize);
        findWidget(ID_HEIGHT)->changeStorage(ySize);
        findWidget(ID_EXTENDED)->changeStorage(usesExtended);
        findWidget(ID_EFFECTS)->changeStorage(usesEffects);
        findWidget(ID_TILESET)->changeStorage(tilesetId);
    }
    
    // Fill listbox with tilesets (non-font)
    WListBox* l = dynamic_cast<WListBox*>(findWidget(ID_TILESET));
    const WorldEdit* world = layer->getWorldEdit();

    l->clear();
    int found = 0;
    World::TileSetIndex::const_iterator end = world->endTileSet();
    for (World::TileSetIndex::const_iterator pos = world->beginTileSet(); pos != end; ++pos) {
        const TileSetEdit* ts = dynamic_cast<TileSetEdit*>((*pos).second);
        if (!ts->getIsFont()) {
            ++found;
            l->addItem(ListEntry(ts->getName(), ts->getId()));
        }
    }
    
    // No tilesets? disallow tileset option
    int allowTileLayer = 1;
    if (!found) {
        if (typeInt == Layer::LAYER_TILE) {
            // Should never get here with LAYER_TILE type unless a new layer,
            // if there's no tile sets
            assert(allowTypeChange);
            typeInt = Layer::LAYER_EMPTY;
        }
        
        allowTileLayer = 0;
    }
    else {
        l->sortItems();
    }

    for (int pos = 0; pos < 4; ++pos) {
        WRadioButton* radio = dynamic_cast<WRadioButton*>(findWidget(ID_TYPE, pos));
        int value = radio->getValue();
        // Disable tile layers specifically, in some circumstances
        // Disable all layer types if not allowing type changes
        if (((value == Layer::LAYER_TILE) && (!allowTileLayer)) || (!allowTypeChange)) radio->disable();
        else radio->enable();
    }
    
    // Hit OK?
    if (runModal() == ID_OK) {
        *type = (Layer::LayerType)typeInt;
        return 1;
    }
    return 0;
}

